﻿using System;
using System.Net;
#if SL4BETA
using System.Windows.Interop;
#else
using System.Windows.Interop;
using System.Runtime.InteropServices.Automation;
#endif
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Collections.Generic;
using System.Text;

/* From http://silverlightcom.codeplex.com */
namespace Silverlight.Mainline.InjectionHelper.IO
{
    public enum AdoFileMode
    {
        Create = 1,
        OpenOrCreate = 2
    }

    public static class File
    {
        private static dynamic fileSystemObject;

        static File()
        {
            if (System.Windows.Application.Current.HasElevatedPermissions)
            {
#if SL4BETA
                fileSystemObject = ComAutomationFactory.CreateObject("Scripting.FileSystemObject");
#else
                fileSystemObject = AutomationFactory.CreateObject("Scripting.FileSystemObject");
#endif
            }
            else
            {
                fileSystemObject = null;
            }
        }

        public static void Copy(string sourceFileName, string destFileName, bool overwrite = false)
        {
            fileSystemObject.CopyFile(sourceFileName, destFileName, overwrite);
        }

        public static AdoFileStream Create(string path)//, int bufferSize, FileOptions options);
        {
            return new AdoFileStream(path, FileMode.CreateNew, FileAccess.ReadWrite);
        }

        public static void Delete(string path)
        {
            if (Exists(path))
                fileSystemObject.DeleteFile(path);
        }

        public static bool Exists(string path)
        {
            return fileSystemObject.FileExists(path);
        }

        public static System.IO.FileAttributes GetAttributes(string path)
        {
            throw new NotImplementedException();
        }

        public static void Move(string sourceFileName, string destFileName)
        {
            fileSystemObject.MoveFile(sourceFileName, destFileName);
        }

        public static AdoFileStream Open(string path, System.IO.FileMode mode, System.IO.FileAccess access)//, FileShare share)
        {
            return new AdoFileStream(path, mode, access);
        }

        public static AdoFileStream OpenRead(string path)//, FileAccess access, FileShare share)
        {
            return new AdoFileStream(path, FileMode.Open, FileAccess.Read);
        }

        public static System.IO.StreamReader OpenText(string path)//, FileAccess access, FileShare share)
        {
            throw new NotImplementedException();
        }

        public static AdoFileStream OpenWrite(string path, FileAccess access = FileAccess.Write)//, FileShare share)
        {
            return new AdoFileStream(path, FileMode.Open, access);
        }

        public static byte[] ReadAllBytes(string path)
        {
            using (var file = OpenRead(path))
            {
                using (var sr = new BinaryReader(file))
                {
                    return sr.ReadBytes((int)file.Length); //TODO: Throw exception if file to large.
                }
            }
        }

        public static string[] ReadAllLines(string path)//, Encoding encoding)
        {
            throw new NotImplementedException();
        }

        public static string ReadAllText(string path)
        {
            return ReadAllText(path, System.Text.Encoding.UTF8);
        }
        public static string ReadAllText(string path, System.Text.Encoding encoding)
        {
            using (var file = OpenRead(path))
            {
                using (var sr = new StreamReader(file, encoding))
                {
                    return sr.ReadToEnd();
                }
            }
        }

        public static void WriteAllBytes(string path, byte[] bytes)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                using (var sr = new BinaryWriter(file))
                {
                    sr.Write(bytes);
                    file.Flush();
                }
            }
        }

        public static void WriteAllLines(string path, string[] contents)//, Encoding encoding)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                using (var sr = new StreamWriter(file))
                {
                    foreach (var line in contents)
                    {
                        sr.WriteLine(line);
                    }
                }
            }
        }

        public static void WriteAllText(string path, string contents)
        {
            WriteAllText(path, contents, System.Text.Encoding.UTF8);
        }

        public static void WriteAllText(string path, string contents, System.Text.Encoding encoding)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                using (var sr = new StreamWriter(file, encoding))
                {
                    sr.Write(contents);
                }
            }
        }

        public static void AppendAllLines(string path, IEnumerable<string> contents)
        {
            AppendAllLines(path, contents, System.Text.Encoding.UTF8);
        }

        public static void AppendAllLines(string path, IEnumerable<string> contents, Encoding encoding)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                file.Position = file.Length;
                using (var sr = new StreamWriter(file, encoding))
                {
                    foreach (var line in contents)
                    {
                        sr.WriteLine(line);
                    }
                }
            }
        }

        public static void AppendAllText(string path, string contents)
        {
            AppendAllText(path, contents, System.Text.Encoding.UTF8);
        }

        public static void AppendAllText(string path, string contents, Encoding encoding)
        {
            using (var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
            {
                file.Position = file.Length;
                using (var sr = new StreamWriter(file, encoding))
                {
                    sr.Write(contents);
                }
            }
        }

        public static StreamWriter AppendText(string path)
        {
            var file = new AdoFileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
            file.Position = file.Length;
            return new StreamWriter(file);
        }
    }
}
